<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Runnable vs Callable | Java并发编程</title>
    <link rel="stylesheet" href="https://cdn.staticfile.org/font-awesome/6.4.0/css/all.min.css">
    <link rel="stylesheet" href="https://cdn.staticfile.org/tailwindcss/2.2.19/tailwind.min.css">
    <link href="https://fonts.googleapis.com/css2?family=Noto+Serif+SC:wght@400;500;600;700&family=Noto+Sans+SC:wght@300;400;500;700&display=swap" rel="stylesheet">
    <script src="https://cdn.jsdelivr.net/npm/mermaid@latest/dist/mermaid.min.js"></script>
    <style>
        body {
            font-family: 'Noto Sans SC', Tahoma, Arial, Roboto, "Droid Sans", "Helvetica Neue", "Droid Sans Fallback", "Heiti SC", "Hiragino Sans GB", Simsun, sans-serif;
            color: #333;
            line-height: 1.6;
        }
        h1, h2, h3, h4 {
            font-family: 'Noto Serif SC', serif;
            font-weight: 600;
        }
        .hero-gradient {
            background: linear-gradient(135deg, #6e8efb 0%, #a777e3 100%);
        }
        .card-hover:hover {
            transform: translateY(-5px);
            box-shadow: 0 10px 25px rgba(0, 0, 0, 0.1);
        }
        .code-block {
            background-color: #2d2d2d;
            color: #f8f8f2;
            border-radius: 6px;
            font-family: 'Courier New', Courier, monospace;
        }
        .comparison-card {
            transition: all 0.3s ease;
        }
        .comparison-card:hover {
            transform: translateY(-3px);
            box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1);
        }
        .feature-icon {
            width: 48px;
            height: 48px;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            margin: 0 auto 1rem;
        }
    </style>
</head>
<body class="bg-gray-50">
    <!-- Hero Section -->
    <section class="hero-gradient text-white py-20 px-4 md:px-0">
        <div class="container mx-auto max-w-6xl text-center">
            <h1 class="text-4xl md:text-5xl font-bold mb-6">Java并发编程核心概念</h1>
            <p class="text-xl md:text-2xl mb-8 max-w-3xl mx-auto">深入理解Runnable与Callable接口的区别与应用场景</p>
            <div class="flex justify-center space-x-4">
                <a href="#comparison" class="bg-white text-purple-700 hover:bg-purple-100 px-6 py-3 rounded-lg font-medium transition duration-300">核心区别</a>
                <a href="#applications" class="border-2 border-white text-white hover:bg-white hover:text-purple-700 px-6 py-3 rounded-lg font-medium transition duration-300">应用场景</a>
            </div>
        </div>
    </section>

    <!-- Introduction Section -->
    <section class="py-16 px-4 md:px-0">
        <div class="container mx-auto max-w-6xl">
            <div class="text-center mb-12">
                <h2 class="text-3xl font-bold mb-4">多线程编程的基石</h2>
                <p class="text-gray-600 max-w-3xl mx-auto">
                    Runnable和Callable是Java并发编程中两个核心接口，它们为多线程任务执行提供了基础能力。
                    虽然功能相似，但设计理念和使用方式却有着本质区别，理解这些差异对于编写高效、健壮的并发程序至关重要。
                </p>
            </div>
            
            <div class="grid md:grid-cols-2 gap-8 mb-16" id="comparison">
                <!-- Runnable Card -->
                <div class="bg-white rounded-xl shadow-md overflow-hidden comparison-card">
                    <div class="bg-blue-600 px-6 py-4">
                        <h3 class="text-white text-2xl font-bold flex items-center">
                            <i class="fas fa-running mr-3"></i> Runnable接口
                        </h3>
                    </div>
                    <div class="p-6">
                        <div class="mb-6">
                            <h4 class="font-semibold text-lg text-blue-600 mb-2">返回值</h4>
                            <p class="text-gray-700">run()方法不返回任何结果，仅执行任务</p>
                            <div class="code-block p-4 mt-3">
                                <code>public void run()</code>
                            </div>
                        </div>
                        
                        <div class="mb-6">
                            <h4 class="font-semibold text-lg text-blue-600 mb-2">异常处理</h4>
                            <p class="text-gray-700">不能抛出受检异常，必须在方法内部处理</p>
                        </div>
                        
                        <div>
                            <h4 class="font-semibold text-lg text-blue-600 mb-2">使用示例</h4>
                            <div class="code-block p-4">
                                <pre>Runnable task = () -> {
    System.out.println("Task running");
};
new Thread(task).start();</pre>
                            </div>
                        </div>
                    </div>
                </div>
                
                <!-- Callable Card -->
                <div class="bg-white rounded-xl shadow-md overflow-hidden comparison-card">
                    <div class="bg-purple-600 px-6 py-4">
                        <h3 class="text-white text-2xl font-bold flex items-center">
                            <i class="fas fa-exchange-alt mr-3"></i> Callable接口
                        </h3>
                    </div>
                    <div class="p-6">
                        <div class="mb-6">
                            <h4 class="font-semibold text-lg text-purple-600 mb-2">返回值</h4>
                            <p class="text-gray-700">call()方法可以返回结果，类型由泛型T指定</p>
                            <div class="code-block p-4 mt-3">
                                <code>public T call() throws Exception</code>
                            </div>
                        </div>
                        
                        <div class="mb-6">
                            <h4 class="font-semibold text-lg text-purple-600 mb-2">异常处理</h4>
                            <p class="text-gray-700">可以抛出受检异常，调用方可以捕获处理</p>
                        </div>
                        
                        <div>
                            <h4 class="font-semibold text-lg text-purple-600 mb-2">使用示例</h4>
                            <div class="code-block p-4">
                                <pre>Callable&lt;Integer&gt; task = () -> {
    return 123;
};
ExecutorService executor = Executors.newSingleThreadExecutor();
Future&lt;Integer&gt; future = executor.submit(task);
Integer result = future.get();</pre>
                            </div>
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </section>

    <!-- Feature Comparison Section -->
    <section class="py-16 bg-gray-100 px-4 md:px-0">
        <div class="container mx-auto max-w-6xl">
            <h2 class="text-3xl font-bold text-center mb-12">核心特性对比</h2>
            
            <div class="grid md:grid-cols-3 gap-8">
                <!-- Feature 1 -->
                <div class="bg-white p-8 rounded-xl shadow-sm text-center">
                    <div class="feature-icon bg-blue-100 text-blue-600">
                        <i class="fas fa-undo text-xl"></i>
                    </div>
                    <h3 class="text-xl font-semibold mb-3">返回值</h3>
                    <p class="text-gray-600">
                        Runnable无返回值，Callable可以返回计算结果，这是它们最显著的区别。
                    </p>
                </div>
                
                <!-- Feature 2 -->
                <div class="bg-white p-8 rounded-xl shadow-sm text-center">
                    <div class="feature-icon bg-purple-100 text-purple-600">
                        <i class="fas fa-exclamation-triangle text-xl"></i>
                    </div>
                    <h3 class="text-xl font-semibold mb-3">异常处理</h3>
                    <p class="text-gray-600">
                        Runnable必须内部处理异常，而Callable允许将异常抛出由调用方处理。
                    </p>
                </div>
                
                <!-- Feature 3 -->
                <div class="bg-white p-8 rounded-xl shadow-sm text-center">
                    <div class="feature-icon bg-green-100 text-green-600">
                        <i class="fas fa-tasks text-xl"></i>
                    </div>
                    <h3 class="text-xl font-semibold mb-3">执行方式</h3>
                    <p class="text-gray-600">
                        Runnable可直接通过Thread执行，Callable需要通过ExecutorService提交。
                    </p>
                </div>
            </div>
        </div>
    </section>

    <!-- Application Scenarios -->
    <section class="py-16 px-4 md:px-0" id="applications">
        <div class="container mx-auto max-w-6xl">
            <h2 class="text-3xl font-bold text-center mb-12">适用场景分析</h2>
            
            <div class="grid md:grid-cols-2 gap-8">
                <div class="bg-white p-8 rounded-xl shadow-sm">
                    <h3 class="text-2xl font-semibold mb-4 text-blue-600 flex items-center">
                        <i class="fas fa-running mr-3"></i> Runnable适用场景
                    </h3>
                    <ul class="space-y-3">
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span>简单的异步任务执行，如日志记录、状态更新</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span>不需要返回结果的多线程任务</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span>可以直接通过Thread启动的轻量级任务</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span>异常处理简单或不需要特殊处理的场景</span>
                        </li>
                    </ul>
                </div>
                
                <div class="bg-white p-8 rounded-xl shadow-sm">
                    <h3 class="text-2xl font-semibold mb-4 text-purple-600 flex items-center">
                        <i class="fas fa-exchange-alt mr-3"></i> Callable适用场景
                    </h3>
                    <ul class="space-y-3">
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span>需要返回计算结果的任务，如数据查询、复杂计算</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span>需要处理复杂异常的任务</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span>需要通过Future获取执行状态和结果的场景</span>
                        </li>
                        <li class="flex items-start">
                            <i class="fas fa-check-circle text-green-500 mt-1 mr-2"></i>
                            <span>线程池管理的并发任务执行</span>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
    </section>

    <!-- Visualization Section -->
    <section class="py-16 bg-gray-100 px-4 md:px-0">
        <div class="container mx-auto max-w-6xl">
            <h2 class="text-3xl font-bold text-center mb-12">执行流程对比</h2>
            
            <div class="bg-white p-8 rounded-xl shadow-sm">
                <div class="mermaid">
                    graph TD
                        subgraph Runnable执行流程
                            A[创建Runnable对象] --> B[创建Thread对象]
                            B --> C[调用start()方法]
                            C --> D[执行run()方法]
                            D --> E[任务完成]
                        end

                        subgraph Callable执行流程
                            F[创建Callable对象] --> G[创建ExecutorService]
                            G --> H[submit()提交任务]
                            H --> I[返回Future对象]
                            I --> J[执行call()方法]
                            J --> K[获取Future.get()结果]
                        end
                </div>
            </div>
        </div>
    </section>

    <!-- Conclusion Section -->
    <section class="py-16 px-4 md:px-0">
        <div class="container mx-auto max-w-4xl">
            <div class="bg-white p-8 md:p-12 rounded-xl shadow-sm">
                <h2 class="text-3xl font-bold text-center mb-8">如何选择合适的方式?</h2>
                
                <div class="prose max-w-none">
                    <p class="text-lg mb-6">
                        选择使用Runnable还是Callable主要取决于您的具体需求：
                    </p>
                    
                    <div class="bg-blue-50 border-l-4 border-blue-500 p-4 mb-6">
                        <h3 class="font-semibold text-blue-700 mb-2">Runnable更适合：</h3>
                        <ul class="list-disc pl-5 space-y-2">
                            <li>简单的后台任务，不需要返回结果</li>
                            <li>直接使用Thread类启动的轻量级任务</li>
                            <li>异常处理简单或不需要特殊处理的场景</li>
                        </ul>
                    </div>
                    
                    <div class="bg-purple-50 border-l-4 border-purple-500 p-4 mb-6">
                        <h3 class="font-semibold text-purple-700 mb-2">Callable更适合：</h3>
                        <ul class="list-disc pl-5 space-y-2">
                            <li>需要返回计算结果的任务</li>
                            <li>需要灵活处理异常的场景</li>
                            <li>需要通过Future控制任务执行的情况</li>
                            <li>使用线程池管理的并发任务</li>
                        </ul>
                    </div>
                    
                    <p class="text-lg mt-6">
                        在实际开发中，Runnable更为常见，但在需要返回结果或更复杂的异常处理时，Callable提供了更强大的能力。理解它们的差异有助于您编写更高效、更健壮的并发代码。
                    </p>
                </div>
            </div>
        </div>
    </section>

    <!-- Footer -->
    <footer class="bg-gray-900 text-white py-12 px-4 md:px-0">
        <div class="container mx-auto max-w-6xl">
            <div class="text-center">
                <h3 class="text-xl font-semibold mb-4">技术小馆</h3>
                <p class="mb-4">探索编程世界的无限可能</p>
                <a href="http://www.yuque.com/jtostring" class="text-blue-400 hover:text-blue-300 transition duration-300">www.yuque.com/jtostring</a>
            </div>
        </div>
    </footer>

    <script>
        mermaid.initialize({
            startOnLoad: true,
            theme: 'default',
            flowchart: {
                useMaxWidth: true,
                htmlLabels: true,
                curve: 'basis'
            }
        });
        
        // 平滑滚动
        document.querySelectorAll('a[href^="#"]').forEach(anchor => {
            anchor.addEventListener('click', function (e) {
                e.preventDefault();
                document.querySelector(this.getAttribute('href')).scrollIntoView({
                    behavior: 'smooth'
                });
            });
        });
    </script>
</body>
</html>